﻿using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.IO;
using System.Linq;
using System.Text;
using System.Transactions;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using Eking.Framework;
using Meres.Models;
using MeresModeling;
using Orchard.Themes;

namespace Meres.Controllers
{
    [Themed]
    public class PeopleController : Controller
    {
        public PartialViewResult Index()
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                return PartialView("PeopleView",
                                   new PeopleViewModel
                                       {
                                           Categories = MeresMainController.Model.PersonCategories.ToList()
                                       });

            }
        }

        public JsonResult PersonInfo(int personId)
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                var person = MeresMainController.Model.People.Single(p => p.Id == personId);
                var txt = this.RenderPartialViewToString("PeopleView.PersonDetail", person);

                return Json(
                    new
                        {
                            ViewModel = new
                                        {
                                            pId = person.Id,
                                            CatId = person.PersonCategories.Id,
                                            CatName = person.PersonCategories.Name,
                                            fieldSets = MakePersonFieldSetViewModel(person)
                                        },
                            Html = txt
                        }, JsonRequestBehavior.AllowGet);

            }
        }

        private object MakePersonFieldSetViewModel(Person person)
        {
            var output = new List<object>();

            foreach (var personData in person.PersonDatas)
            {
                output.Add(new
                    {
                        fsetId = personData.Id,
                        fsetData = personData.Ext
                    });
            }

            return output;
        }

        public JsonResult PeopleCardView(int catId)
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                var model = MeresMainController.Model;
                List<Person> data;
                if (catId < 0)
                    data = (from p in model.People
                            orderby p.Name
                            select p).ToList();
                else
                    data = (from p in model.People
                            orderby p.Name
                            where p.PersonCategories.Id == catId
                            select p).ToList();

                var html = this.RenderPartialViewToString("PeopleView.PeopleCardView", data);

                return Json(
                    new
                        {
                            ViewModel = data.Select(p => new
                                {
                                    p.Id,
                                    p.Name,
                                    catId = p.PersonCategories.Id,
                                    catName = p.PersonCategories.Name
                                }).ToList(),
                            Html = html
                        }, JsonRequestBehavior.AllowGet);

            }
        }

        public PartialViewResult PersonSelector()
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                var model = MeresMainController.Model;
                return PartialView("PersonSelector", new PeopleViewModel
                                                         {
                                                             Categories = model.PersonCategories.ToList(),
                                                             Persons = model.People.OrderBy(p => p.Name).ToList()
                                                         });
                
            }
        }

        public PartialViewResult NewPersonControl()
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                var model = MeresMainController.Model;
                this.ViewBag.Categories = model.PersonCategories.ToList();
                this.ViewBag.Groups = model.MembershipGroups.ToList();
                this.ViewBag.Person = new Person();
                return PartialView("NewPersonControl");
            }
        }

        public int AddNewPerson(Person input)
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                var model = MeresMainController.Model;
                var cat = model.PersonCategories.Single(c => c.Id == input.PersonCategories.Id);
                input.PersonCategories = cat;
                model.People.AddObject(input);
                model.SaveChanges();

                return input.Id;
            }
        }

        public void RemovePerson(int personId)
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                var model = MeresMainController.Model;
                var person = model.People.Single(p => p.Id == personId);
                model.People.DeleteObject(person);
                model.SaveChanges();
            }
        }

        public JsonResult GetPerson(int personId)
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                var person = MeresMainController.Model.People.Single(p => p.Id == personId);
                return Json(new { person.Id, person.Name }, JsonRequestBehavior.AllowGet);
            }
        }

        public JsonResult GetPeopleSimple(FormCollection filter)
        {
            dynamic categoryIdVal = filter["CategoryId"];
            int categoryId = categoryIdVal == null ? -1 : int.Parse(categoryIdVal);

            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                var query = categoryId == -1 ?
                                 MeresMainController.Model.People.ToList()
                                 : MeresMainController.Model.PersonCategories.Single(c => c.Id == categoryId).Person.ToList();

                var people = query.OrderBy(o => o.Name).Select(p => new { p.Id, p.Name });

                return Json(people, JsonRequestBehavior.AllowGet);
            }
        }

        public JsonResult PeoplejqGridQuery(string sidx, string sord, int page, int rows,
                bool _search, string searchField, string searchOper, string searchString, int catId)
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                var cDate = DateTime.Now.AddYears(-2);
                var model = MeresMainController.Model;
                Person[] query;
                if (catId < 0)
                    query = (from p in model.People
                             orderby p.Name
                             select p).ToArray();
                else
                    query = (from p in model.People
                             orderby p.Name
                             where p.PersonCategories.Id == catId
                             select p).ToArray();


                var jsonData = new
                {
                    total = 5, // total page
                    page = 0,
                    records = model.People.Count(), // total item
                    rows = query.Select(p =>
                        new
                    {
                        id = p.Id,
                        cell = new object[]{
                            p.Id,
                            p.Name,
                            p.PersonCategories.Name,
                            DateTime.Now,
                            cDate
                        }
                    }).ToList()
                };

                return Json(jsonData, JsonRequestBehavior.AllowGet);
            }
        }


        public int AddOrUpdatePersonFieldSet(int pId, int fsetId, string fdata)
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                var model = MeresMainController.Model;
                var person = model.People.Single(p => p.Id == pId);
                PersonData pdata = null;
                if (fsetId < 0)
                {
                    pdata = new PersonData { Ext = fdata };
                    person.PersonDatas.Add(pdata);
                }
                else
                {
                    pdata = person.PersonDatas.Single(p => p.Id == fsetId);
                    pdata.Ext = fdata;
                }

                model.SaveChanges();

                return pdata.Id;
            }
        }

        public void DeletePersonFieldSet(int fsetId)
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                var model = MeresMainController.Model;
                var set = model.PersonDatas.Single(f => f.Id == fsetId);
                set.Person.PersonDatas.Remove(set);
                model.SaveChanges();
            }
        }

        public class MyModelBinder : DefaultModelBinder
        {
            protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
            {
                var typeValue = bindingContext.ValueProvider.GetValue("typename");
                if (typeValue == null)
                {
                    throw new Exception("Impossible to instantiate a model. The \"typeName\" query string parameter was not provided.");
                }
                var type = Type.GetType(
                    (string)typeValue.ConvertTo(typeof(string)),
                    true
                );
                var model = Activator.CreateInstance(type);
                bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type);
                return model;
            }
        }
    }
}